﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Xml;
using System.Windows.Forms;
using System.Xml.Linq;
using MicrobloggingInterface;
using System.IO;
using System.Text;

namespace HexunMicrobloggingClientUI
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            MainForm.CheckForIllegalCrossThreadCalls = false;

            #region Initialize 'Issue' related data and settings.

            string elementValue, isEnabled, isChecked;

            ReadFromConfigureFile("userName", out elementValue);
            tbUserName.Text = elementValue;

            ReadFromConfigureFile("password", out elementValue);
            tbPassword.Text = elementValue;

            ReadFromConfigureFile("rememberMe", "enabled", out isEnabled);
            cbRememberMe.Enabled = bool.Parse(isEnabled);
            ReadFromConfigureFile("rememberMe", "checked", out isChecked);
            cbRememberMe.Checked = bool.Parse(isChecked);

            ReadFromConfigureFile("rememberPwd", "enabled", out isEnabled);
            cbRememberPwd.Enabled = bool.Parse(isEnabled);
            ReadFromConfigureFile("rememberPwd", "checked", out isChecked);
            cbRememberPwd.Checked = bool.Parse(isChecked);

            #endregion

            #region Initialize 'Batch Issue' ListView Header And Row Selection Style.

            InitListViewHeader();
            lvBatchIssue.FullRowSelect = true;
            lvBatchIssue.HeaderStyle = ColumnHeaderStyle.Clickable;

            #endregion

            #region Initialize MessageBoxManager.

            //mbm.AutoClose = true;
            //mbm.AutoCloseResult = DialogResult.OK;
            //mbm.HookEnabled = true;
            //mbm.CenterWindow = true;

            #endregion

            #region Initialize Send button

            enterSendToolStripMenuItem.Checked = true;
            ctrlEnterSendToolStripMenuItem.Checked = false;

            #endregion

            #region Initialize timer of rich text box

            textBoxFocusTimer.Elapsed += new System.Timers.ElapsedEventHandler(FocusTextBox);

            #endregion
        }

        #region MainForm EventHandler related.

        /// <summary>
        /// MainForm load event handler.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private void MainForm_Load(object sender, EventArgs e)
        {
        }

        #endregion

        #region MessageBoxManager related.

        /// <summary>
        /// Instance of MassageBoxManager.
        /// </summary>
        //private MessageBoxManager mbm = new MessageBoxManager();

        /// <summary>
        /// Show an auto close message box above parent form's center.
        /// </summary>
        /// <param name="text">Message content.</param>
        /// <param name="autoClose">If need auto close.</param>
        /// <param name="timeOutInSeconds">Auto close time out in seconds.</param>
        private void ShowMessageBox(string text, bool autoClose, int timeOutInSeconds)
        {
            //mbm.AutoClose = autoClose;
            //mbm.TimeOut = timeOutInSeconds;
            MessageBox.Show(text);

            /* Usage history:
            CodeProject.Dialog.MsgBox.Show("Success");
            
            mbm.TimeOut = 1;
            MessageBox.Show("Success");
            */
        }

        #endregion

        #region ListView related.

        /// <summary>
        /// Initialize the header of list view control(Batch Issue).
        /// </summary>
        private void InitListViewHeader()
        {
            lvBatchIssue.View = System.Windows.Forms.View.Details;
            lvBatchIssue.MultiSelect = true;
            lvBatchIssue.HideSelection = false;
            lvBatchIssue.HeaderStyle = ColumnHeaderStyle.Nonclickable;

            ColumnHeader columnHeader0 = new ColumnHeader();
            columnHeader0.Text = "User Name";
            columnHeader0.TextAlign = HorizontalAlignment.Left;
            columnHeader0.Width = 140;

            ColumnHeader columnHeader1 = new ColumnHeader();
            columnHeader1.Text = "Status";
            columnHeader1.TextAlign = HorizontalAlignment.Center;
            columnHeader1.Width = 100;

            ColumnHeader columnHeader2 = new ColumnHeader();
            columnHeader2.Text = "Detail";
            columnHeader2.TextAlign = HorizontalAlignment.Center;
            columnHeader2.Width = 100;

            lvBatchIssue.Columns.Add(columnHeader0);
            lvBatchIssue.Columns.Add(columnHeader1);
            lvBatchIssue.Columns.Add(columnHeader2);

            /*
            string[] foodList = new string[]{
                "Juice", 
                "Coffee", 
                "Cereal & Milk", 
                "Fruit Plate", 
                "Toast & Jelly", 
                "Bagel & Cream Cheese"};
            string[] foodPrice = new string[]{
                "1.09", 
                "1.09", 
                "2.19", 
                "2.49", 
                "1.49", 
                "1.49"};

            for (int count = 0; count < foodList.Length; count++)
            {
                ListViewItem listItem = new ListViewItem(foodList[count]);

                listItem.SubItems.Add(foodPrice[count]);
                listItem.SubItems.Add(foodPrice[count]);

                lvBatchIssue.Items.Add(listItem);
            }
            */
        }

        #endregion

        #region Click 'Send' button or Press 'Enter' or 'Ctrl + Enter' buttons

        /// <summary>
        /// Timer for focus on the rich text box.
        /// </summary>
        System.Timers.Timer textBoxFocusTimer = new System.Timers.Timer(100);

        private void toolStripSplitButton1_ButtonClick(object sender, EventArgs e)
        {
            if (SendViaBtn())
            {
                rtbContent.Clear();
                tssBtnSend.Enabled = false;
            }

            rtbContent.Focus();
        }

        private void enterSendToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (enterSendToolStripMenuItem.Checked)
            {
                ctrlEnterSendToolStripMenuItem.Checked = false;
            }
            else
            {
                enterSendToolStripMenuItem.Checked = true;
            }
        }

        private void ctrlEnterSendToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (ctrlEnterSendToolStripMenuItem.Checked)
            {
                enterSendToolStripMenuItem.Checked = false;
            }
            else
            {
                ctrlEnterSendToolStripMenuItem.Checked = true;
            }
        }

        private void rtbContent_KeyUp(object sender, KeyEventArgs e)
        {
            if (!tssBtnSend.Enabled)
            {
                return;
            }

            // Press 'Enter' but not Ctrl and enable 'press enter to send' function.
            if (e.KeyCode == Keys.Enter && !e.Control &&
                enterSendToolStripMenuItem.Checked)
            {
                // Send microblogging message.
                string contentWithTrim = rtbContent.Text.Trim();
                if (!string.IsNullOrEmpty(contentWithTrim))
                {
                    if (SendViaBtn())
                    {
                        rtbContent.Clear();
                        tssBtnSend.Enabled = false;
                    }
                    else
                    {
                        rtbContent.Text = rtbContent.Text.Substring(0, rtbContent.TextLength - 1);
                        textBoxFocusTimer.Start();
                    }
                }
            }

            // Press 'Ctrl + Enter' and enable 'press ctrl + enter to send' function.
            if (e.Control && e.KeyCode == Keys.Enter &&
                ctrlEnterSendToolStripMenuItem.Checked)
            {
                // Send microblogging message.
                if (SendViaBtn())
                {
                    rtbContent.Clear();
                    tssBtnSend.Enabled = false;
                }
                else
                {
                    rtbContent.Text = rtbContent.Text.Substring(0, rtbContent.TextLength - 1);
                }
            }

            // Below two methods are works too.
            //if (e.KeyData == (Keys.Control | Keys.Enter))
            //{
            //    Send();
            //}
            // Or....
            //if (e.KeyCode == Keys.Enter && Control.ModifierKeys == Keys.Control)
            //{
            //    Send();
            //}
        }

        private void FocusTextBox(object sender, System.Timers.ElapsedEventArgs e)
        {
            textBoxFocusTimer.Stop();
            rtbContent.Focus();
        }

        private bool SendViaBtn()
        {
            //rtbContent.Enabled = false;
            //ShowMessageBox("Failed: " + "test failed", false, 1);
            //rtbContent.Enabled = true;
            //return false;

            string errorMessage = string.Empty;
            string userName = tbUserName.Text.Trim();
            string password = tbPassword.Text;
            string content = rtbContent.Text;

            string responseType;
            string responseContent;

            if (CoreFunc.Send(userName, password, content, out responseType, out responseContent, out errorMessage))
            {
                ShowMessageBox("Success", true, 1);
                return true;
            }
            else
            {
                ShowMessageBox("Failed: " + errorMessage, false, 1);
                return false;
            }
        }

        #endregion

        #region Type & Count words

        private const int MAX_CONTENT_LENGTH = 140;

        /// <summary>
        /// Content Text Changed Event Handler.
        /// </summary>
        /// <param name="sender">The evert sender.</param>
        /// <param name="e">The event arguments.</param>
        private void rtbContent_TextChanged(object sender, EventArgs e)
        {
            string messageContent = ((RichTextBox)sender).Text.Trim();

            // If message content is null, disable the 'Send' button.
            if (string.IsNullOrEmpty(messageContent))
            {
                tssBtnSend.Enabled = false;
                return;
            }
            else
            {
                tssBtnSend.Enabled = true;
            }

            // Check the message content length, 
            // if large than 140, show warning text and disable the 'Send' button.
            int sum = CountMixedChars(messageContent);
            int temp = sum / 2;
            if (temp < 0)
            {
                temp = 0;
            }

            int temp2 = MAX_CONTENT_LENGTH - temp;
            if (MAX_CONTENT_LENGTH * 2 < sum)
            {
                var chao = 0;
                if (sum % 2 == 1)
                    chao = -temp2 + 1;
                else
                    chao = -temp2;

                lblCharNumber.Text = chao.ToString();

                lblCharNumber.ForeColor = Color.Red;
                lblDescription.Text = "Need to delete.";
                tssBtnSend.Enabled = false;
            }
            else
            {
                lblCharNumber.Text = temp2.ToString();

                lblCharNumber.ForeColor = Color.Black;
                lblDescription.Text = "Words left.";
                tssBtnSend.Enabled = true;
            }
        }

        /// <summary>
        /// Count mixed characters of ASCII and others, like Chinese.
        /// For other characters, one for two ASCII characters.
        /// </summary>
        /// <param name="txtstring">Text for count.</param>
        /// <returns>Sum number of characters.</returns>
        private int CountMixedChars(string txtstring)
        {
            int charactersCounter = 0, objectsCounter = 0;
            for (var i = 0; i < txtstring.Length; i++)
            {
                // If not ASCII.
                if ((int)txtstring[i] < 127)
                {
                    charactersCounter++;
                }
                else
                {
                    objectsCounter++;
                }
            }
            return charactersCounter + objectsCounter * 2;
        }

        #endregion

        #region Remember Me & Remember Pwd

        /// <summary>
        /// CheckBox's CheckedChanged Event Handler of 'RememberMe' CheckBox.
        /// </summary>
        /// <param name="sender">Sender of event.</param>
        /// <param name="e">The event arguments.</param>
        private void cbRememberMe_CheckedChanged(object sender, EventArgs e)
        {
            cbRememberPwd.Enabled = ((CheckBox)sender).Checked;

            string userNameToConfigureFile = string.Empty;
            if (((CheckBox)sender).Checked)
            {
                userNameToConfigureFile = tbUserName.Text.Trim();
            }
        }

        /// <summary>
        /// CheckBox's CheckedChanged Event Handler of 'RememberPwd' CheckBox.
        /// </summary>
        /// <param name="sender">Sender of event.</param>
        /// <param name="e">The event arguments.</param>
        private void cbRememberPwd_CheckedChanged(object sender, EventArgs e)
        {
            string passwordToConfigureFile = string.Empty;
            if (((CheckBox)sender).Checked)
            {
                passwordToConfigureFile = tbPassword.Text;
            }
        }

        /// <summary>
        /// The 'btnSave' button click event handler.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            WriteToConfigureFile("rememberMe", "enabled", cbRememberMe.Enabled.ToString());
            WriteToConfigureFile("rememberMe", "checked", cbRememberMe.Checked.ToString());
            WriteToConfigureFile("userName", (cbRememberMe.Enabled && cbRememberMe.Checked) ? tbUserName.Text.Trim() : "");

            WriteToConfigureFile("rememberPwd", "enabled", cbRememberPwd.Enabled.ToString());
            WriteToConfigureFile("rememberPwd", "checked", cbRememberPwd.Checked.ToString());
            WriteToConfigureFile("password", (cbRememberPwd.Enabled && cbRememberPwd.Checked) ? tbPassword.Text : "");
        }

        /// <summary>
        /// Write to configure file.
        /// </summary>
        /// <param name="elementName">Element name.</param>
        /// <param name="elementValue">Element value.</param>
        /// <param name="isEnabled">If the specified element's 'enabled' attribute's value is True.</param>
        /// <param name="isChecked">If the specified element's 'checked' attribute's value is True.</param>
        private void WriteToConfigureFile(string elementName, string elementValue)
        {
            XElement root = XElement.Load(configFile);
            var userData = from el in root.Elements("accountSettings").Elements("singleUser").Elements(elementName)
                           select el;
            XElement elUserData = userData.ElementAt(0);
            elUserData.Value = elementValue;

            root.Save(configFile);
        }

        private void WriteToConfigureFile(string elementName, string attributeName, string attributeValue)
        {
            XElement root = XElement.Load(configFile);
            var userData = from el in root.Elements("accountSettings").Elements("singleUser").Elements(elementName)
                           select el;
            XElement elUserData = userData.ElementAt(0);
            elUserData.Attribute(attributeName).Value = attributeValue;

            root.Save(configFile);
        }

        /// <summary>
        /// Read from configure file.
        /// </summary>
        /// <param name="elementName">Element name.</param>
        /// <param name="elementValue">Element value.</param>
        private void ReadFromConfigureFile(string elementName, out string elementValue)
        {
            elementValue = string.Empty;

            XElement root = XElement.Load(configFile);
            var userData = from el in root.Elements("accountSettings").Elements("singleUser").Elements(elementName)
                           select el;
            XElement elUserData = userData.ElementAt(0);
            elementValue = elUserData.Value;
        }

        private void ReadFromConfigureFile(string elementName, string attributeName, out string attributeValue)
        {
            attributeValue = string.Empty;

            XElement root = XElement.Load(configFile);
            var userData = from el in root.Elements("accountSettings").Elements("singleUser").Elements(elementName)
                           select el;
            XElement elUserData = userData.ElementAt(0);
            attributeValue = elUserData.Attribute(attributeName).Value;
        }

        private string configFile = System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name.Replace(".dll", ".config").Replace(".exe", ".config");

        #endregion

        #region Batch Issue Related MenuItem Click Events.

        private static List<TaskStatus> taskStatusList = new List<TaskStatus>();

        #region Add - New

        private void newToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            NewTaskForm newTask = new NewTaskForm();
            if (newTask.ShowDialog() == DialogResult.OK)
            {
                // Values from newTask form.
                string userName = newTask.UserName;
                string password = newTask.Password;
                int delayTime = newTask.DelayTime;
                int timerInterval = newTask.TimerInterval;
                int maxCountNum = newTask.MaxCountNum;
                bool countEvenIfFailed = newTask.CountEvenIfFailed;
                string textContent = newTask.textSource.Text;
                EnumTextType enumTextType = newTask.textSource.EnumTextType;

                TaskStatus taskStatus = new TaskStatus();
                // Create TimerCallback and System.Threading.Timer instance.
                System.Threading.TimerCallback timerDelegate = new System.Threading.TimerCallback(jobTimerElesped);
                System.Threading.Timer timer = new System.Threading.Timer(timerDelegate, taskStatus, delayTime, timerInterval);
                taskStatus.timer = timer;
                taskStatus.userName = userName;
                taskStatus.password = password;
                taskStatus.textContent = textContent;
                taskStatus.enumTextType = enumTextType;
                taskStatus.indexOfList = taskStatusList.Count;
                taskStatus.maxCountNum = maxCountNum;
                taskStatus.countEvenIfFailed = countEvenIfFailed;
                taskStatusList.Add(taskStatus);

                // Add task item to ListView.
                ListViewItem listItem = new ListViewItem(userName);
                listItem.SubItems.Add("Not Started");
                listItem.SubItems.Add("");
                lvBatchIssue.Items.Add(listItem);
            }
        }

        /// <summary>
        /// The envent handler of Timer of taskStatus.
        /// </summary>
        /// <param name="status"></param>
        private void jobTimerElesped(Object status)
        {
            TaskStatus taskStatus = (TaskStatus)status;

            // Set event handler of task status type changed.
            taskStatus.taskStatusTypeChanged += new TaskStatusTypeChangedEventHandler(taskStatus_taskStatusTypeChanged);

            // Self update.
            taskStatus.curTotalCount++;
            taskStatus.SetTaskStatus(TaskStatusType.Started);

            // Get text content.
            string textContent = taskStatus.textContent;
            if (taskStatus.enumTextType.Equals(EnumTextType.RSSUri))
            {
                textContent = CrawlTextContent(taskStatus.indexOfList, textContent);
            }

            Logger.GetLogger().Debug("Before sending message.");
            Logger.GetLogger().Debug("textType: " + taskStatus.enumTextType.ToString());
            Logger.GetLogger().Debug("textContent: " + textContent);

            // Declare the errorMessage and the result UI Showing message.
            string errorMessage, resultUIMessage;
            // Declare the response type, response content and error messages in response.
            string responseType, responseContent, statusCode = string.Empty;

            // Send microblogging messages.
            bool sendResult = SendViaTask(taskStatus.indexOfList, taskStatus.curTotalCount,
                taskStatus.userName, taskStatus.password, textContent, 
                out responseType, out responseContent, out errorMessage);

            Logger.GetLogger().Debug("After sending message.");
            Logger.GetLogger().Debug("responseType: " + responseType);
            Logger.GetLogger().Debug("responseContent: " + responseContent);
            Logger.GetLogger().Debug("errorMessage: " + errorMessage);

            bool realResult = false;
            if (sendResult)
            {
                // realResult : 
                // If the response is a WARNING of content repeat or some others,
                // realResult will be false, and the content will not be send to account.

                if (!string.IsNullOrEmpty(responseContent)
                    && (responseType.Equals("Xml") || responseType.Equals("Json")))
                {
                    realResult = GetResultFromResponse(responseType, responseContent, out statusCode);
                    Logger.GetLogger().Debug("realResult: " + realResult.ToString());
                    Logger.GetLogger().Debug("statusCode: " + statusCode);

                    if (!realResult)
                    {
                        Logger.GetLogger().Error("realResult: " + realResult.ToString());
                        Logger.GetLogger().Error("statusCode: " + statusCode);
                    }
                }

                // Only if the realResut is true, the cursuccessCount counter will curSuccessCount++
                if (realResult)
                {
                    taskStatus.curSuccessCount++;
                    resultUIMessage = string.Format("Success(Count: {0})", taskStatus.curSuccessCount);
                    Logger.GetLogger().Debug("taskStatus.curSuccessCount: " + taskStatus.curSuccessCount);
                }
                else
                {
                    taskStatus.curFailedCount++;
                    resultUIMessage = string.Format("Failed(Count: {0}): {1}", taskStatus.curFailedCount, statusCode);
                    Logger.GetLogger().Error("taskStatus.curFailedCount: " + taskStatus.curFailedCount);
                }
            }
            else
            {
                taskStatus.curFailedCount++;
                resultUIMessage = string.Format("Failed(Count: {0}): {1}", taskStatus.curFailedCount, errorMessage);
                Logger.GetLogger().Error("taskStatus.curFailedCount: " + taskStatus.curFailedCount);
            }

            // Remember the last send result.
            taskStatus.successWithResponseFailed = sendResult && !realResult;


            // Update task result message to list view.
            ListViewItem jobItem = lvBatchIssue.Items[taskStatus.indexOfList];
            jobItem.SubItems[2].Text = resultUIMessage;

            // If current count equals to the max count number.
            if (taskStatus.finishedTaskCount.Equals(taskStatus.maxCountNum))
            {
                taskStatus.timer.Dispose();
                taskStatus.timer = null;

                taskStatus.SetTaskStatus(TaskStatusType.Finished);
            }

            // Update TaskStatus instance to taskStatusList.
            taskStatusList[taskStatus.indexOfList] = taskStatus;
        }

        private bool GetResultFromResponse(string responseType, string responseContent, out string statusCode)
        {
            statusCode = string.Empty;

            // Parse Xml response.
            if (responseType.Equals("Xml"))
            {
                MemoryStream stream = new MemoryStream( Encoding.GetEncoding("UTF-8").GetBytes(responseContent) );
                XElement root = XElement.Load(stream);
                
                // Get is_success value.
                var isSuccessList = from el in root.Elements("status").Elements("is_success") select el;
                bool isSuccess = isSuccessList.ElementAt(0).Value.Equals("1");

                // Get has_record value.
                var hasRecordList = from el in root.Elements("status").Elements("has_record") select el;
                bool hasRecord = hasRecordList.ElementAt(0).Value.Equals("1");

                // Get status_code value.
                var statusCodeList = from el in root.Elements("status").Elements("status_code") select el;
                statusCode = statusCodeList.ElementAt(0).Value;

                return isSuccess && hasRecord;
            }

            if (responseType.Equals("Json"))
            {
                return true;
            }

            return true;
        }

        private string CrawlTextContent(int taskIndex, string rssUris)
        {
            Subscriber subscriber = Subscriber.GetInstance(taskIndex, rssUris);
            return subscriber.GetRSSContent();
        }
        
        /// <summary>
        /// The event handler of taskStatusTypeChange, the status information showed in items will be updated automatically.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">The event arguments.</param>
        private void taskStatus_taskStatusTypeChanged(object sender, TaskStatusTypeChangedEventArgs e)
        {
            TaskStatus taskStatus = (TaskStatus)sender;
            if (taskStatus == null)
            {
                return;
            }

            int indexOfList = taskStatus.indexOfList;
            TaskStatusType curTaskStatusType = taskStatus.TaskStatusType;

            // Update the second column(Status) of list view.
            ListViewItem jobItem = lvBatchIssue.Items[indexOfList];
            jobItem.SubItems[1].Text = curTaskStatusType.ToString();

            // If current list view item is selected.
            if (!jobItem.Selected)
            {
                return;
            }

            if (lvBatchIssue.SelectedItems == null && lvBatchIssue.SelectedItems.Count == 0)
            {
                return;
            }

            // If selected items' count > 1
            if (lvBatchIssue.SelectedItems.Count > 1)
            {
                return;
            }

            UpdateButtonsStatus(indexOfList);
        }

        private bool SendViaTask(int jobIndex, int counter, 
                                 string userName, string password, 
                                 string content, 
                                 out string responseType, out string responseContent,
                                 out string errorMessage)
        {
            string strLog = string.Format("Job Index: {0}, Count: {1}", jobIndex, counter);
            Logger.GetLogger().Debug(strLog);

            return CoreFunc.Send(userName, password, content, 
                out responseType, out responseContent, out errorMessage);
        }

        #endregion

        #region Add - Import

        private void importToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        #endregion

        #region Start

        private void startToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //lvBatchIssue.CheckedItems

        }

        #endregion

        #region Pause

        private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        #endregion

        #region Stop

        private void stopToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        #endregion

        #region Delete

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        #endregion

        #region Configure

        private void configureToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        #endregion

        private void button1_Click(object sender, EventArgs e)
        {

        }

        #endregion

        private int SelectedIndex { get; set; }

        private void lvBatchIssue_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            
        }

        private void lvBatchIssue_SelectedIndexChanged(object sender, EventArgs e)
        {
            ListView listView = (ListView)sender;
            ListView.SelectedListViewItemCollection selectedItems = listView.SelectedItems;
            if (selectedItems == null && selectedItems.Count == 0)
            {
                return;
            }

            if (selectedItems.Count == 1)
            {
                ListViewItem item = listView.FocusedItem;
                if (item.Focused && item.Selected)
                {
                    SelectedIndex = item.Index;
                    UpdateButtonsStatus(SelectedIndex);
                }
            }
            else
            {
                // Multi selection.
            }
        }

        private void UpdateButtonsStatus(int index)
        {
            if (taskStatusList.Count == 0)
            {
                return;
            }

            TaskStatus taskStatus = taskStatusList[index];
            switch (taskStatus.TaskStatusType)
            {
                case TaskStatusType.NotStarted:
                    startToolStripMenuItem.Enabled = true;
                    pauseToolStripMenuItem.Enabled = false;
                    stopToolStripMenuItem.Enabled = false;
                    deleteToolStripMenuItem.Enabled = true;
                    configureToolStripMenuItem.Enabled = true;
                    break;
                case TaskStatusType.Started:
                    startToolStripMenuItem.Enabled = false;
                    pauseToolStripMenuItem.Enabled = true;
                    stopToolStripMenuItem.Enabled = true;
                    deleteToolStripMenuItem.Enabled = false;
                    configureToolStripMenuItem.Enabled = false;
                    break;
                case TaskStatusType.Paused:
                    startToolStripMenuItem.Enabled = true;
                    pauseToolStripMenuItem.Enabled = false;
                    stopToolStripMenuItem.Enabled = true;
                    deleteToolStripMenuItem.Enabled = true;
                    configureToolStripMenuItem.Enabled = true;
                    break;
                case TaskStatusType.Stoped:
                    startToolStripMenuItem.Enabled = true;
                    pauseToolStripMenuItem.Enabled = true;
                    stopToolStripMenuItem.Enabled = false;
                    deleteToolStripMenuItem.Enabled = true;
                    configureToolStripMenuItem.Enabled = true;
                    break;
                case TaskStatusType.Finished:
                    startToolStripMenuItem.Enabled = false;
                    pauseToolStripMenuItem.Enabled = false;
                    stopToolStripMenuItem.Enabled = false;
                    deleteToolStripMenuItem.Enabled = true;
                    configureToolStripMenuItem.Enabled = false;
                    break;
                default:
                    break;
            }

            // Disable the 'Delete' button.
            deleteToolStripMenuItem.Enabled = false;
        }
    }
}